package cn.android666.audiorecorder.aac

import cn.android666.audiorecorder.objectpool.ByteBufferPool
import cn.android666.audiorecorder.pcm.PCMProcessThread
import timber.log.Timber
import java.nio.ByteBuffer
import java.util.concurrent.ArrayBlockingQueue
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean

/**
 * AAC编码器线程
 * @param sampleRateInHz 指定PCM音频数据的采样率
 * @param channelCount 指定PCM音频数据的通道数量
 * @param maxInputSize 指定每次送入AAC编码器的PCM音频数据的最大大小
 */
class AACEncodeThread(sampleRateInHz: Int, channelCount: Int, maxInputSize: Int, pcmByteBufferPool: ByteBufferPool) : PCMProcessThread(pcmByteBufferPool) {

    private val aacEncoder = AACEncoder(sampleRateInHz, channelCount, maxInputSize, pcmByteBufferPool)
    private val pcmQueue = ArrayBlockingQueue<ByteBuffer>(3)
    private var needRun = AtomicBoolean(true)
    private var count = 0
    private var totalTime = 0L

    override fun addPcmToQueue(byteBuffer: ByteBuffer) {
        val isSuccess = pcmQueue.offer(byteBuffer)
        if (!isSuccess) {
            Timber.e("编码aac时队列装不下了，丢帧")
        }
    }

    override fun run() {
        android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO)
        while (needRun.get()) {
            pcmQueue.poll(30L, TimeUnit.MILLISECONDS)?.let { byteBuffer ->
//                val start = System.currentTimeMillis()
                aacEncoder.encodePCMToAAC(byteBuffer)
//                calculationTime(start)
            }
        }
        aacEncoder.encodePCMToAAC(ByteBuffer.allocate(0)) // 放入一个空Buffer来告诉编码器没数据了应该结束编码了
    }

    /** 计算每编码10帧pcm所需要的时间 */
    private fun calculationTime(start: Long) {
        totalTime = totalTime + System.currentTimeMillis() - start
        if (++count == 10) {
            Timber.i("每编10帧pcm所需时间：$totalTime")
            count = 0
            totalTime = 0L
        }
    }

    override fun close() {
        needRun.set(false)
    }

}